home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 11 / QRZ Ham Radio Callsign Database - Volume 11.iso / files / packet / ax25ip.shr / tty_ax.c < prev   
C/C++ Source or Header  |  1998-02-02  |  24KB  |  1,087 lines

  1. /*
  2.  * KISS+AX25 IP streams module for sunos 4.x
  3.  *
  4.  * Copyright 1991, 1992 by Theo de Raadt
  5.  *
  6.  * Theo de Raadt <deraadt@lego.cuc.ab.ca>
  7.  * Thanks to William Graham <uug@indigo.cuc.ab.ca> for AX25 specs.
  8.  *
  9.  * Streams ideas ripped off from PPP and SLIP implimentations for
  10.  * Sunos by Brad Clements and Rayan Zachariassen respectively.
  11.  */
  12. #undef    DEBUG
  13. #undef    DEBUG2
  14. #define    AX_NIT
  15.  
  16. #include "ax.h"
  17. #if NAX > 0
  18.  
  19. #include <sys/types.h>
  20. #include <sys/param.h>
  21. #include <sys/stream.h>
  22. #include <sys/stropts.h>
  23. #include <sys/dir.h>
  24. #include <sys/signal.h>
  25. #include <sys/user.h>
  26. #include <sys/mbuf.h>
  27. #include <sys/socket.h>
  28. #include <sys/sockio.h>
  29. #include <sys/syslog.h>
  30.  
  31. #include <netinet/in.h>
  32.  
  33. #include <net/if.h>
  34. #include <net/nit_if.h>
  35. #include <netinet/if_ether.h>
  36. #include <sys/if_ax.h>
  37.  
  38. #include <net/netisr.h>
  39.  
  40. #include <netinet/in_systm.h>
  41. #include <netinet/in_var.h>
  42. #include <netinet/ip.h>
  43.  
  44. #ifdef AX_NIT
  45. static struct ether_header nitheader = { {{1}}, {{2}}, ETHERTYPE_IP };
  46. static struct nit_if nif = {(caddr_t)&nitheader, sizeof(nitheader), 0, 0};
  47.  
  48. static struct ether_header nitheader_arp = { {{1}}, {{2}}, ETHERTYPE_ARP };
  49. static struct nit_if nif_arp = {(caddr_t)&nitheader_arp, sizeof(nitheader_arp), 0, 0};
  50. #endif
  51.  
  52. int ax_attach();
  53. static int ax_open(), ax_close(), ax_rput(), ax_wput(), ax_wsrv();
  54. static int ax_ioctl(), ax_output();
  55. static struct mbuf *ax_btom();
  56.  
  57. static struct module_info minfo = {
  58.     0xabce, AXSTREAMNAME, 0, INFPSZ, 16384, 4096
  59. };
  60.  
  61. static struct qinit r_init = {
  62.     ax_rput, NULL, ax_open, ax_close, NULL, &minfo, NULL
  63. };
  64.  
  65. static struct qinit w_init = {
  66.     ax_wput, ax_wsrv, ax_open, ax_close, NULL, &minfo, NULL
  67. };
  68.  
  69. struct streamtab axinfo = {
  70.     &r_init, &w_init, NULL, NULL, NULL
  71. };
  72.  
  73. static struct axpriv {
  74.     struct arpcom    arpcom;
  75.     queue_t        *q;
  76.     u_char        *buf;
  77.     u_char        *dp;
  78.     u_int        inlen;
  79.     u_char        gotesc, toobig;
  80. } axpriv[NAX];
  81.  
  82. static u_char ax25broadcastaddr[7] = {
  83.     'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
  84. };
  85. static struct ether_addr ethernulladdr;
  86.  
  87. int
  88. ax_attach(unit)
  89. int unit;
  90. {
  91.     register struct ifnet *ifp = &axpriv[unit].arpcom.ac_if;
  92.  
  93.     ifp->if_name = AXIFNAME;
  94.     ifp->if_mtu = AX25MTU;
  95.     ifp->if_flags = IFF_BROADCAST;
  96.     ifp->if_unit = unit;
  97.     ifp->if_ioctl = ax_ioctl;
  98.     ifp->if_output = ax_output;
  99.     ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  100.     if_attach(ifp);
  101.     return 0;
  102. }
  103.  
  104. static int
  105. ax_open(q, dev, flag, sflag)
  106. queue_t *q;
  107. dev_t dev;
  108. int flag, sflag;
  109. {
  110.     struct axpriv *axp;
  111.     int unit, s;
  112.  
  113.     if( !suser()) {
  114.         u.u_error = EPERM;
  115.         return OPENFAIL;
  116.     }
  117.  
  118.     s = splstr();
  119.     for( unit=0; unit<NAX; ++unit) {
  120.         axp = &axpriv[unit];
  121.  
  122.         if(axp->buf)
  123.             continue;
  124.         if(axp->arpcom.ac_if.if_mtu == 0)
  125.             ax_attach(unit);
  126.         axp->arpcom.ac_if.if_flags |= IFF_RUNNING;
  127.         axp->buf = (u_char *)kmem_alloc(AX25MTU);
  128.         axp->dp = axp->buf + sizeof(struct ifnet *);
  129.         axp->inlen = 0;
  130.         axp->q = WR(q);
  131.         WR(q)->q_ptr = q->q_ptr = (caddr_t)axp;
  132.         (void) splx(s);
  133.         log(LOG_INFO, "ax%d: coming up\n", unit);
  134.         return unit;
  135.     }
  136.     splx(s);
  137.     log(LOG_INFO, "ax%d: no more devices available\n", NAX);
  138.     return OPENFAIL;
  139. }
  140.  
  141. static int
  142. ax_close(q, flag)
  143. queue_t *q;
  144. int flag;
  145. {
  146.     struct axpriv *axp;
  147.     int s;
  148.  
  149.     s = splimp();
  150.     axp = (struct axpriv *)q->q_ptr;
  151.     if(axp) {
  152.         log(LOG_INFO, "ax%d: going down\n", axp->arpcom.ac_if.if_unit);
  153.         if_down(&axp->arpcom.ac_if);
  154.         axp->arpcom.ac_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
  155.         if(axp->buf)
  156.             kmem_free(axp->buf, AX25MTU);
  157.         axp->buf = NULL;
  158.         axp->q = NULL;
  159.     }
  160.     (void) splx(s);
  161. }
  162.  
  163. static int
  164. ax_wput(q, mp)
  165. queue_t *q;
  166. mblk_t *mp;
  167. {
  168.     struct axpriv *axp;
  169.     char ax25[7];
  170.     struct iocblk *iocp;
  171.  
  172.     switch(mp->b_datap->db_type) {
  173.     case M_FLUSH:
  174.         if(*mp->b_rptr & FLUSHW)
  175.             flushq(q, FLUSHDATA);
  176.         putnext(q, mp);
  177.         break;
  178.     case M_DATA:
  179.         putq(q, mp);
  180.         break;
  181.     case M_IOCTL:
  182.         iocp = (struct iocblk *)mp->b_rptr;
  183.         axp = (struct axpriv *)q->q_ptr;
  184.         switch(iocp->ioc_cmd) {
  185.         case AXIOSHADDR:
  186.             bcopy((caddr_t)mp->b_cont->b_rptr,
  187.                 (caddr_t)&axp->arpcom.ac_enaddr,
  188.                 sizeof(struct ether_addr));
  189.             mp->b_datap->db_type = M_IOCACK;
  190.             iocp->ioc_rval = iocp->ioc_count = iocp->ioc_error = 0;
  191.             qreply(q, mp);
  192.             log(LOG_INFO, "ax%d: ether %2x:%2x:%2x:%2x:%2x:%2x ax25 ",
  193.                 axp->arpcom.ac_if.if_unit,
  194.                 axp->arpcom.ac_enaddr.ether_addr_octet[0],
  195.                 axp->arpcom.ac_enaddr.ether_addr_octet[1],
  196.                 axp->arpcom.ac_enaddr.ether_addr_octet[2],
  197.                 axp->arpcom.ac_enaddr.ether_addr_octet[3],
  198.                 axp->arpcom.ac_enaddr.ether_addr_octet[4],
  199.                 axp->arpcom.ac_enaddr.ether_addr_octet[5]);
  200.             ax_ether2ax(&axp->arpcom.ac_enaddr, ax25);
  201.             print_ax25addr(ax25);
  202.             printf("\n");
  203.             return;
  204.         case AXIOGUNIT:
  205.             iocp->ioc_rval = 0;
  206.             if( mp->b_cont = allocb(sizeof(int), BPRI_MED) ) {
  207.                 u_char *cp = mp->b_cont->b_wptr;
  208.  
  209.                 mp->b_datap->db_type = M_IOCACK;
  210.                 *((int *)cp) = axp->arpcom.ac_if.if_unit;
  211.                 mp->b_cont->b_wptr += sizeof(int);
  212.                 iocp->ioc_count = sizeof(int);
  213.                 iocp->ioc_error = 0;
  214.                 qreply(q, mp);
  215.                 break;
  216.             }
  217.             iocp->ioc_error = ENOSR;
  218.             mp->b_datap->db_type = M_IOCNAK;
  219.             qreply(q, mp);
  220.             return;
  221.         default:
  222.             log(LOG_INFO, "ax%d: unknown ioc %8x\n",
  223.                 axp->arpcom.ac_if.if_unit, iocp->ioc_cmd);
  224.             putnext(q, mp);
  225.             return;
  226.         }
  227.         break;
  228.     default:
  229.         putnext(q, mp);
  230.     }
  231. }
  232.  
  233. static int
  234. ax_rput(q, mp)
  235. queue_t *q;
  236. mblk_t *mp;
  237. {
  238.     struct axpriv *axp = (struct axpriv *)q->q_ptr;
  239.     struct ifnet *ifp;
  240.     register u_char c, *rp;
  241.     register mblk_t *bp;
  242.     struct mbuf *m;
  243.     int proto, forus, s;
  244.  
  245.     if( axp==NULL ) {
  246.         log(LOG_INFO, "ax_rput: axp is NULL\n");
  247.         freemsg(mp);
  248.         return;
  249.     }
  250.     if( axp->buf==NULL ) {
  251.         log(LOG_INFO, "ax_rput: axp->buf is NULL\n");
  252.         freemsg(mp);
  253.         return;
  254.     }
  255.  
  256.     ifp = &axp->arpcom.ac_if;
  257.     switch(mp->b_datap->db_type) {
  258.     case M_DATA:
  259.         break;
  260.     case M_FLUSH:
  261.         if(*mp->b_rptr & FLUSHR)
  262.             flushq(q, FLUSHDATA);
  263.         putnext(q, mp);
  264.         return;
  265.     case M_UNHANGUP:
  266.         log(LOG_INFO, "ax%d: M_UNHANGUP\n", ifp->if_unit);
  267.         axp->q = WR(q);        /* hook us up again */
  268.         putnext(q, mp);
  269.         putctl1(q->q_next, M_PCSIG, SIGURG);
  270.         return;
  271.     case M_HANGUP:
  272.         log(LOG_INFO, "ax%d: M_HANGUP\n", ifp->if_unit);
  273.         s = splstr();
  274.         axp->q = NULL;        /* cause ax_output to return ENETDOWN */
  275.         (void) splx(s);
  276.         putnext(q, mp);
  277.         return;
  278.     case M_BREAK:
  279.     case M_IOCACK:
  280.         putnext(q, mp);
  281.         return;
  282.     default:
  283.         log(LOG_INFO, "ax%d: rput streams message type %d discarded\n",
  284.             ifp->if_unit, mp->b_datap->db_type);
  285.         putnext(q, mp);
  286.         return;
  287.     }
  288.  
  289.     /*
  290.      * Perform the KISS protocol on the streams message, and add the bytes
  291.      * to a packet reconstruction buffer. When a complete AX25 packet has
  292.      * been collected, strip the AX25 layer and provide the IP (or ARP) packet
  293.      * inside to the networking code.
  294.      */
  295.     for( bp=mp; bp; bp=bp->b_cont) {
  296.         rp = bp->b_rptr;
  297.         while( rp < bp->b_wptr) {
  298.             c = *rp++;
  299.             /*printf("K %2x\n", c);*/
  300.             if(axp->gotesc) {
  301.                 axp->gotesc = 0;
  302.                 if(c==KISS_TEND)
  303.                     c = KISS_END;
  304.                 else if(c==KISS_TESC)
  305.                     c = KISS_ESC;
  306. #ifdef DEBUG
  307.                 else
  308.                     log(LOG_INFO, "ax%d: kiss ESC error (c=%d)\n",
  309.                         ifp->if_unit, c);
  310. #endif
  311.             } else if(c==KISS_END) {
  312.                 if(axp->toobig) {
  313.                     axp->toobig = 0;
  314.                     /*printf("ax%d: packet toobig\n",
  315.                         ifp->if_unit);*/
  316.                     axp->inlen = 0;
  317.                     continue;
  318.                 }
  319.                 if(axp->inlen==0)
  320.                     continue;
  321.             
  322.                 /*
  323.                  * buf contains KISS_DATA followed by an AX25
  324.                  * packet. Extract the IP packet lurking inside
  325.                  * AX25 packet..
  326.                  */
  327.                 m = ax_btom(axp, &proto, &forus);
  328.                 axp->dp = axp->buf + sizeof(struct ifnet *);
  329.                 ifp->if_ipackets++;
  330.                 axp->inlen = 0;
  331.                 if(!m) {
  332.                     ifp->if_ierrors++;
  333.                     continue;
  334.                 }
  335.  
  336.                 switch(proto) {
  337.                 case AX25PID_IP:
  338. #ifdef AX_NIT
  339.                     if(ifp->if_flags & IFF_PROMISC) {
  340.                         struct mbuf *nm = m;
  341.                         int len = 0;
  342.  
  343.                         do {
  344.                             len += nm->m_len;
  345.                         } while( nm=nm->m_next );
  346.                         len -= sizeof(struct ifnet *);
  347.                         m->m_off += sizeof(struct ifnet *);
  348.                         nif.nif_bodylen = len;
  349.                         snit_intr(&axp->arpcom, m, &nif);
  350.                         m->m_off -= sizeof(struct ifnet *);
  351.                     }                    
  352. #endif
  353.                     if(!forus) {
  354.                         m_freem(m);
  355.                         break;
  356.                     }
  357.                     s = splimp();
  358.                     if( IF_QFULL(&ipintrq) ) {
  359.                         IF_DROP(&ipintrq);
  360.                         ifp->if_ierrors++;
  361.                         m_freem(m);
  362.                         (void) splx(s);
  363.                     } else {
  364.                         IF_ENQUEUE(&ipintrq, m);
  365.                         schednetisr(NETISR_IP);
  366.                         (void) splx(s);
  367. #ifdef DEBUG
  368.                         log(LOG_INFO, "handing off to IP\n");
  369. #endif
  370.                     }
  371.                     break;
  372.                 case AX25PID_ARP:
  373. #ifdef AX_NIT
  374.                     if(ifp->if_flags & IFF_PROMISC) {
  375.                         struct mbuf *nm = m;
  376.                         int len = 0;
  377.  
  378.                         do {
  379.                             len += nm->m_len;
  380.                         } while( nm=nm->m_next );
  381.                         len -= sizeof(struct ifnet *);
  382.                         m->m_off += sizeof(struct ifnet *);
  383.                         nif_arp.nif_bodylen = len;
  384.                         snit_intr(&axp->arpcom, m, &nif_arp);
  385.                         m->m_off -= sizeof(struct ifnet *);
  386.                     }                    
  387. #endif
  388.                     if(!forus) {
  389.                         m_freem(m);
  390.                         break;
  391.                     }
  392. #ifdef DEBUG
  393.                     printf("[INCOMING ethernet arp packet]");
  394.                     ax25_arpdebug(m);
  395. #endif
  396.                     arpinput(&axp->arpcom, m);
  397.                     break;
  398.                 default:
  399. #ifdef DEBUG2
  400.                     printf("ax%d: unknown protocol %d\n",
  401.                         ifp->if_unit,
  402.                         proto);
  403. #endif
  404.                     m_freem(m);
  405.                     break;
  406.                 }
  407.                 continue;
  408.             } else if(c==KISS_ESC) {
  409.                 axp->gotesc = 1;
  410.                 continue;
  411.             }
  412.             if(++axp->inlen > AX25MTU) {
  413.                 if(axp->toobig)
  414.                     continue;
  415.                 axp->toobig = 1;
  416.                 ifp->if_ierrors++;
  417.                 axp->dp = axp->buf + sizeof(struct ifnet *);
  418.                 continue;
  419.             } else
  420.                 *axp->dp++ = c;
  421.         }
  422.         bp->b_rptr = rp;
  423.     }
  424.     freemsg(mp);
  425.     return;
  426. }
  427.  
  428.  
  429. static struct mbuf *
  430. ax_btom(axp, protop, forusp)
  431. struct axpriv *axp;
  432. int *protop, *forusp;
  433. {
  434.     struct ax25_hdr *ax;
  435.     struct mbuf *m, **mp, *top = NULL;
  436.     struct ifnet *ifp;
  437.     struct ether_addr oureth;
  438.     int len, count;
  439.     caddr_t cp;
  440.  
  441.     ax = (struct ax25_hdr *)(axp->buf + sizeof(struct ifnet *) + 1);
  442.  
  443.     /*
  444.      * digipeaters are not supported (they could be supported - could
  445.      * correct the AX25 packet's fields, KISS encode it, and send a
  446.      * message downstream to the TNC.)
  447.      * 
  448.      * The IP packet must come in an AX25 UI frame.
  449.      */
  450.     if(ax->ah_cmd != AX25CMD_UI) {
  451. #ifdef DEBUG2
  452.         printf("ax%d: ax25 frame not UI, cmd=%2x\n",
  453.             axp->arpcom.ac_if.if_unit, ax->ah_cmd);
  454. #endif
  455.         return NULL;
  456.     }
  457.  
  458. #ifdef DEBUG2
  459.     printf("ax%d: ", axp->arpcom.ac_if.if_unit);
  460.     print_ax25addr(ax->ah_src);
  461.     printf("->");
  462.     print_ax25addr(ax->ah_dst);
  463.     printf(" [%d]\n", axp->inlen - sizeof(struct ax25_hdr) - 1);
  464. #endif
  465.  
  466.     /* 
  467.      * is this packet to us?
  468.      */
  469.     *forusp = 1;
  470.     ax_ax2ether(ax->ah_dst, &oureth);
  471.     if( bcmp((caddr_t)&oureth, (caddr_t)&axp->arpcom.ac_enaddr,
  472.         sizeof oureth) &&
  473.         bcmp((caddr_t)ax25broadcastaddr, (caddr_t)&axp->arpcom.ac_enaddr,
  474.         sizeof oureth)) {
  475.         *forusp = 0;
  476.     }
  477.  
  478.     /*
  479.      * packet not for us, and not promisc mode --> can out.
  480.      */
  481.     if( !(axp->arpcom.ac_if.if_flags & IFF_PROMISC) && *forusp==0)
  482.         return NULL;
  483.  
  484.     /*
  485.      * check acceptable protocols
  486.      */
  487.     switch(ax->ah_pid) {
  488.     case AX25PID_IP:
  489.     case AX25PID_ARP:
  490.         break;
  491.     default:
  492. #ifdef DEBUG2
  493.         printf("ax%d: packet discarded - protocol %d\n",
  494.             axp->arpcom.ac_if.if_unit, ax->ah_pid);
  495. #endif
  496.         return NULL;
  497.     }
  498.  
  499.     *protop = (int)(ax->ah_pid);
  500.     ifp = &axp->arpcom.ac_if;
  501.     cp = (caddr_t)(axp->buf + sizeof(struct ifnet *) + 1 + sizeof(struct ax25_hdr));
  502.     mp = ⊤
  503.     len = axp->inlen - 1 - sizeof(struct ax25_hdr);
  504.     while(len>0) {
  505.         MGET(m, M_DONTWAIT, MT_DATA);
  506.         if(m == NULL) {
  507.             if(top)
  508.                 m_freem(top);
  509.             return NULL;
  510.         }
  511.         *mp = m;
  512.         if(ifp) {
  513.             m->m_off += sizeof(ifp);
  514.             count = MIN(len, MLEN - sizeof(ifp));
  515.             bcopy(cp, mtod(m, caddr_t), count);
  516.             m->m_len = count;
  517.             m->m_off -= sizeof(ifp);
  518.             m->m_len += sizeof(ifp);
  519.             *mtod(m, struct ifnet **) = ifp;
  520.             ifp = NULL;
  521.         } else {
  522.             count = MIN(len, MLEN);
  523.             bcopy(cp, mtod(m, caddr_t), count);
  524.             m->m_len = count;
  525.         }
  526.         cp += count;
  527.         len -= count;
  528.         mp = &m->m_next;
  529.     }
  530.     if(ax->ah_pid== AX25PID_ARP) {
  531.         top->m_off += sizeof(ifp);    /* XXX ax_ax2etherarp() weak */
  532.         ax_ax2etherarp(top);
  533.         top->m_off -= sizeof(ifp);
  534.     }
  535.  
  536.     return top;
  537. }
  538.  
  539.  
  540. static int
  541. ax_wsrv(q)
  542. queue_t *q;
  543. {
  544.     register mblk_t *mp;
  545.  
  546.     while( mp=getq(q) ) {
  547.         if( !canput(q->q_next)) {
  548.             putbq(q, mp);
  549.             return;
  550.         }
  551.         putnext(q, mp);
  552.     }
  553. }
  554.  
  555. /* %%% ifconfig ether #:#:#:#:#:# not working */
  556. static int
  557. ax_ioctl(ifp, cmd, data)
  558. struct ifnet *ifp;
  559. int cmd;
  560. caddr_t data;
  561. {
  562.     register struct ifaddr *ifa = (struct ifaddr *)data;
  563.     register struct ifreq *ifr = (struct ifreq *)data;
  564.     int error = 0, s;
  565.  
  566.     if(ifa==NULL)
  567.         return EFAULT;
  568.     s = splimp();
  569.     switch(cmd) {
  570.     case SIOCSIFFLAGS:
  571.         if(!data)        /* IFF_PROMISC change */
  572.             break;
  573.         if(!suser()) {
  574.             error = EPERM;
  575.             break;
  576.         }
  577.         ifp->if_flags &= IFF_CANTCHANGE;
  578.         ifp->if_flags |= (ifr->ifr_flags & ~IFF_CANTCHANGE);
  579.         break;
  580.     case SIOCGIFFLAGS:
  581.         ifr->ifr_flags = ifp->if_flags;
  582.         break;
  583.     case SIOCSIFADDR:
  584.         switch(ifa->ifa_addr.sa_family) {
  585.         case AF_INET:
  586.             ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
  587.             ifp->if_flags |= IFF_UP;
  588.             break;
  589.         default:
  590.             error = EAFNOSUPPORT;
  591.             break;
  592.         }
  593.         break;
  594.     case SIOCSIFBRDADDR:
  595.         if(ifa->ifa_addr.sa_family != AF_INET)
  596.             error = EAFNOSUPPORT;
  597.         break;
  598.     case SIOCSIFNETMASK:
  599.         if(ifa->ifa_addr.sa_family != AF_INET)
  600.             error = EAFNOSUPPORT;
  601.         break;
  602.     default:
  603.         error = EINVAL;
  604.     }
  605.     (void) splx(s);
  606.     return error;
  607. }
  608.  
  609. static int
  610. ax_output(ifp, m0, dst)
  611. struct ifnet *ifp;
  612. struct mbuf *m0;
  613. struct sockaddr *dst;
  614. {
  615.     struct axpriv *axp;
  616.     struct ax25_hdr ax25;
  617.     struct ether_header *eth;
  618.     struct mbuf *m = m0;
  619.     int i, len, s, n;
  620.     struct in_addr idst;
  621.     u_char *cp, *cp2;
  622.     mblk_t *mp;
  623.  
  624.     axp = &axpriv[ifp->if_unit];
  625.     if(axp->q == NULL)
  626.         return ENETDOWN;
  627.  
  628.     /* printf("ax%d: trying to send packet\n", ifp->if_unit); */
  629.  
  630.     switch(dst->sa_family) {
  631.     case AF_INET:
  632. #ifdef AX_NIT
  633.         if(axp->arpcom.ac_if.if_flags & IFF_PROMISC) {
  634.             struct mbuf *nm = m0;
  635.             int len = 0;
  636.  
  637.             do {
  638.                 len += nm->m_len;
  639.             } while( nm=nm->m_next );
  640.             nif.nif_bodylen = len;
  641.             snit_intr(&axp->arpcom, m0, &nif);
  642.         }                    
  643.  
  644. #endif
  645.         idst = ((struct sockaddr_in *)dst)->sin_addr;
  646.         ((struct arpcom *)ifp)->ac_lastip = idst;
  647.         m = m0;
  648.         if( !arpresolve((struct arpcom *)ifp, m)) {
  649.             return 0;
  650.         }
  651. #ifdef DEBUG2
  652.         len = 0;
  653.         for(m=m0; m; m=m->m_next) {
  654.             cp = mtod(m, u_char *);
  655.             n = m->m_len;
  656.             while(n-->0) {
  657.                 if( !(len++ % 16) )
  658.                     printf("\n\t");
  659.                 printf("%2x ", *cp++);
  660.             }
  661.         }
  662.         if( len % 16 )
  663.             printf("\n");
  664. #endif
  665.         ax25.ah_pid = AX25PID_IP;
  666.         ax_ether2ax(&((struct arpcom *)ifp)->ac_enaddr, ax25.ah_src);
  667.         ax_ether2ax(&((struct arpcom *)ifp)->ac_lastarp, ax25.ah_dst);
  668. #ifdef DEBUG2
  669.         printf("ax%d: sending to ", ifp->if_unit);
  670.         print_ax25addr(ax25.ah_dst);
  671.         printf("\n");
  672. #endif
  673.         break;
  674.     case AF_UNSPEC:
  675.         eth = (struct ether_header *)dst->sa_data;
  676.         switch(eth->ether_type) {
  677.         case ETHERTYPE_ARP:
  678.         case ETHERTYPE_REVARP:
  679. #ifdef AX_NIT
  680.         if(axp->arpcom.ac_if.if_flags & IFF_PROMISC) {
  681.             struct mbuf *nm = m0;
  682.             int len = 0;
  683.  
  684.             do {
  685.                 len += nm->m_len;
  686.             } while( nm=nm->m_next );
  687.             nif_arp.nif_bodylen = len;
  688.             snit_intr(&axp->arpcom, m0, &nif_arp);
  689.         }                    
  690.  
  691. #endif
  692. #ifdef DEBUG2
  693.             printf("AF_UNSPEC: ARP\n");
  694.             printf("[ethernet arp packet]");
  695.             len = 0;
  696.             for(m=m0; m; m=m->m_next) {
  697.                 cp = mtod(m, u_char *);
  698.                 n = m->m_len;
  699.                 while(n-->0) {
  700.                     if( !(len++ % 16) )
  701.                         printf("\n\t");
  702.                     printf("%2x ", *cp++);
  703.                 }
  704.             }
  705.             if( len % 16 )
  706.                 printf("\n");
  707. #endif
  708.  
  709.             ax_ether2axarp(m0);
  710.             ax25.ah_pid = AX25PID_ARP;
  711.             ax_ether2ax(&((struct arpcom *)ifp)->ac_enaddr, ax25.ah_src);
  712.             ax_ether2ax(ð->ether_dhost, ax25.ah_dst);
  713. #ifdef DEBUG2
  714.             printf("[AX25 arp packet]");
  715. #endif
  716.             break;
  717.         default:
  718.             printf("AF_UNSPEC: unknown ether_type %4x",
  719.                 ntohs(eth->ether_type));
  720.             ax25.ah_pid = AX25PID_IP;    /* wrong */
  721.             ax_ether2ax(ð->ether_shost, ax25.ah_src);
  722.             ax_ether2ax(ð->ether_dhost, ax25.ah_dst);
  723.             break;
  724.         }
  725.  
  726. #ifdef DEBUG2
  727.         len = 0;
  728.         for(m=m0; m; m=m->m_next) {
  729.             cp = mtod(m, u_char *);
  730.             n = m->m_len;
  731.             while(n-->0) {
  732.                 if( !(len++ % 16) )
  733.                     printf("\n\t");
  734.                 printf("%2x ", *cp++);
  735.             }
  736.         }
  737.         if( len % 16 )
  738.             printf("\n");
  739. #endif
  740.  
  741.         break;
  742.     default:
  743.         log(LOG_INFO, "ax%d: cannot handle af%d\n", ifp->if_unit,
  744.             dst->sa_family);
  745.         m_freem(m0);
  746.         return EAFNOSUPPORT;
  747.     }
  748.     
  749.     ax25.ah_cmd = AX25CMD_UI;
  750.     ax25.ah_src[6] |= 0x01;    /* %%% set low bit on src */
  751.  
  752.     /*
  753.      * run through the ax25_hdr and the packet buffer counting
  754.      * how much space we need for KISS encoding.
  755.      */
  756.     len = 2;    /* KISS_END, KISS_DATA */
  757.     for(i=0, cp=(u_char *)&ax25; i< sizeof(ax25); i++, cp++) {
  758.         len++;
  759.         if(*cp==KISS_END || *cp==KISS_ESC)
  760.             len++;
  761.     }
  762.     for(m=m0; m; m=m->m_next) {
  763.         cp = mtod(m, u_char *);
  764.         for(i=0; i< m->m_len; i++, cp++) {
  765.             len++;
  766.             if(*cp==KISS_END || *cp==KISS_ESC)
  767.                 len++;
  768.         }
  769.     }
  770.     len++;        /* KISS_END */
  771.  
  772.     if( !(mp = allocb(len, BPRI_MED)) ) {
  773.         log(LOG_INFO, "ax%d: ax_output cannot allocb %d bytes\n",
  774.             ifp->if_unit, len);
  775.         m_freem(m0);
  776.         return ENOSR;
  777.     }
  778.  
  779. #ifdef DEBUG2
  780.     cp2 = mp->b_wptr;
  781. #endif
  782.  
  783.     /*
  784.      * KISS-format the ax25 header and data into mp.
  785.      */
  786.     *mp->b_wptr++ = KISS_END;
  787.     *mp->b_wptr++ = KISS_DATA;
  788.     for(i=0, cp=(u_char *)&ax25; i<sizeof(ax25); i++, cp++) {
  789.         switch(*cp) {
  790.         case KISS_END:
  791.             *mp->b_wptr++ = KISS_ESC;
  792.             *mp->b_wptr++ = KISS_TEND;
  793.             break;
  794.         case KISS_ESC:
  795.             *mp->b_wptr++ = KISS_ESC;
  796.             *mp->b_wptr++ = KISS_TESC;
  797.             break;
  798.         default:
  799.             *mp->b_wptr++ = *cp;
  800.             break;
  801.         }
  802.     }
  803.     for(m=m0; m; m=m->m_next) {
  804.         cp = mtod(m, u_char *);
  805.         for(i=0; i< m->m_len; i++, cp++) {
  806.             switch(*cp) {
  807.             case KISS_END:
  808.                 *mp->b_wptr++ = KISS_ESC;
  809.                 *mp->b_wptr++ = KISS_TEND;
  810.                 break;
  811.             case KISS_ESC:
  812.                 *mp->b_wptr++ = KISS_ESC;
  813.                 *mp->b_wptr++ = KISS_TESC;
  814.                 break;
  815.             default:
  816.                 *mp->b_wptr++ = *cp;
  817.                 break;
  818.             }
  819.         }
  820.     }
  821.     *mp->b_wptr++ = KISS_END;    /* superfluous, really */
  822.  
  823. #ifdef DEBUG2
  824.     printf("actual serial output:\n");
  825.     while(cp2 < mp->b_wptr)
  826.         printf("%2x ", *cp2++);
  827.     printf("\n");
  828. #endif
  829.  
  830.     s = splstr();
  831.     if(axp->q)
  832.         putq(axp->q, mp);
  833.     else
  834.         freemsg(mp);
  835.     (void) splx(s);
  836.     m_freem(m0);
  837.     return 0;
  838. }
  839.  
  840. /*
  841.  * convert an ethernet ARP packet to an AX25 ARP packet. The AX25 frame
  842.  * header is not included.
  843.  */
  844. ax_ether2axarp(m)
  845. struct mbuf *m;
  846. {
  847.     struct arphdr *arp = mtod(m, struct arphdr *);
  848.     struct ether_addr eth1, eth2;
  849.     struct in_addr in1, in2;
  850.     caddr_t cp;
  851.  
  852.     arp->ar_hrd = AX25_HARDTYPE;
  853.     arp->ar_pro = AX25_IPTYPE;
  854.     arp->ar_hln = 7;
  855.  
  856.     cp = ((caddr_t)arp) + sizeof(struct arphdr);
  857.     bcopy(cp, (caddr_t)ð1, sizeof(struct ether_addr));
  858.     cp += sizeof(struct ether_addr);
  859.     bcopy(cp, (caddr_t)&in1, sizeof(struct in_addr));
  860.     cp += sizeof(struct in_addr);
  861.     bcopy(cp, (caddr_t)ð2, sizeof(struct ether_addr));
  862.     cp += sizeof(struct ether_addr);
  863.     bcopy(cp, (caddr_t)&in2, sizeof(struct in_addr));
  864.  
  865.     cp = ((caddr_t)arp) + sizeof(struct arphdr);
  866.     ax_ether2ax(ð1, (u_char *)cp);
  867.     cp += 7;
  868.     bcopy((caddr_t)&in1, cp, sizeof(struct in_addr));
  869.     cp += sizeof(struct in_addr);
  870.     ax_ether2ax(ð2, (u_char *)cp);
  871.     cp += 7;
  872.     bcopy((caddr_t)&in2, cp, sizeof(struct in_addr));
  873.  
  874.     m->m_len += 2;
  875.     return 0;
  876. }
  877.  
  878. /*
  879.  * convert an AX25 ARP packet to an ethernet ARP packet. The AX25 frame
  880.  * is assumed to have been already stripped off.
  881.  */
  882. ax_ax2etherarp(m)
  883. struct mbuf *m;
  884. {
  885.     struct arphdr *arp = mtod(m, struct arphdr *);
  886.     u_char axa1[7], axa2[7];
  887.     struct in_addr in1, in2;
  888.     caddr_t cp;
  889.  
  890. #ifdef DEBUG2
  891.     printf("[INCOMING AX25 arp packet]");
  892.     ax25_arpdebug(m);
  893. #endif
  894.  
  895.     arp->ar_hrd = ARPHRD_ETHER;
  896.     arp->ar_pro = ETHERTYPE_IP;
  897.     arp->ar_hln = sizeof(struct ether_addr);
  898.  
  899.     cp = ((caddr_t)arp) + sizeof(struct arphdr);
  900.     bcopy(cp, (caddr_t)axa1, 7);
  901.     cp += 7;
  902.     bcopy(cp, (caddr_t)&in1, sizeof(struct in_addr));
  903.     cp += sizeof(struct in_addr);
  904.     bcopy(cp, (caddr_t)axa2, 7);
  905.     cp += 7;
  906.     bcopy(cp, (caddr_t)&in2, sizeof(struct in_addr));
  907.  
  908.     cp = ((caddr_t)arp) + sizeof(struct arphdr);
  909.     ax_ax2ether(axa1, (struct ether_addr *)cp);
  910.     cp += sizeof(struct ether_addr);
  911.     bcopy((caddr_t)&in1, cp, sizeof(struct in_addr));
  912.     cp += sizeof(struct in_addr);
  913.     ax_ax2ether(axa2, (struct ether_addr *)cp);
  914.     cp += sizeof(struct ether_addr);
  915.     bcopy((caddr_t)&in2, cp, sizeof(struct in_addr));
  916.  
  917.     m->m_len -= 2;
  918.     return 0;
  919. }
  920.  
  921. /*
  922.  * convert an ax25_addr to an ether_addr
  923.  */
  924. ax_ax2ether(axhp, ethp)
  925. u_char *axhp;
  926. struct ether_addr *ethp;
  927. {
  928.     u_char c;
  929.     int i;
  930.  
  931. #ifdef DEBUG2
  932.     for(i=0; i<6; i++)
  933.         printf("%2x.", axhp[i]);
  934.     printf("%2x '", axhp[6]);
  935.  
  936.     for(i=0; i<(7-1); i++)
  937.         printf("%c", (axhp[i]>>1) & 0x7f );
  938.     printf("-%c' == ", (axhp[6]&0x7f)>>1 & 0x7f );
  939. #endif
  940.  
  941.     if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
  942.         sizeof(ax25broadcastaddr)) ) {
  943.         bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
  944.             sizeof(struct ether_addr));
  945.         goto done;
  946.     }
  947.  
  948.     ethp->ether_addr_octet[0] = 0x99;
  949.     c =  ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
  950.     c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
  951.     ethp->ether_addr_octet[1] = c;
  952.     c =  ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
  953.     c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
  954.     ethp->ether_addr_octet[2] = c;
  955.     c =  ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
  956.     c |= ((((axhp[3]>>1) - ' ')     ) & 0x3f);
  957.     ethp->ether_addr_octet[3] = c;
  958.     c =  ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
  959.     c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
  960.     ethp->ether_addr_octet[4] = c;
  961.     c =  ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
  962.     c |= (((((axhp[6]&0x7f)>>1) - '0')     ) & 0x0f);
  963.     ethp->ether_addr_octet[5] = c;
  964.  
  965. done:
  966. #ifdef DEBUG2
  967.     for(i=0; i<sizeof(struct ether_addr)-1; i++)
  968.         printf("%2x:", ethp->ether_addr_octet[i]);
  969.     printf("%2x\n", ethp->ether_addr_octet[5]);
  970. #endif
  971.     return 0;
  972. }
  973.  
  974. /*
  975.  * convert an ether_addr to an ax25_addr
  976.  */
  977. ax_ether2ax(ethp, axhp)
  978. struct ether_addr *ethp;
  979. u_char *axhp;
  980. {
  981.     u_char c;
  982.     int i;
  983.  
  984. #ifdef DEBUG2
  985.     for(i=0; i<sizeof(struct ether_addr)-1; i++)
  986.         printf("%2x:", ethp->ether_addr_octet[i]);
  987.     printf("%2x == ", ethp->ether_addr_octet[5]);
  988. #endif
  989.  
  990.     if( !bcmp((caddr_t)ethp, (caddr_t)ðernulladdr,
  991.         sizeof(struct ether_addr))) {
  992. #ifdef DEBUG2
  993.         printf("nothing\n");
  994. #endif
  995.         for(i=0; i<7; i++)
  996.             axhp[i] = (u_char)0;
  997.         return;
  998.     }
  999.     if( !bcmp((caddr_t)ethp, (caddr_t)ðerbroadcastaddr,
  1000.         sizeof(struct ether_addr))) {
  1001.         bcopy((caddr_t)ax25broadcastaddr, (caddr_t)axhp,
  1002.             sizeof(ax25broadcastaddr));
  1003.         goto done;
  1004.     }
  1005.     c = ethp->ether_addr_octet[0];
  1006.     if(c != 0x99) {
  1007. #ifdef DEBUG2
  1008.         printf("[NO MAPPING]\n");
  1009. #endif
  1010.         for(i=0; i<7; i++)
  1011.             axhp[i] = (u_char)0;
  1012.         return;
  1013.     }
  1014.     c =  (ethp->ether_addr_octet[1] >> 2) & 0x3f;
  1015.     axhp[0] = (u_char)((c + ' ') << 1);
  1016.     c =  (ethp->ether_addr_octet[1] << 4) & 0x30;
  1017.     c |= (ethp->ether_addr_octet[2] >> 4) & 0x0f;
  1018.     axhp[1] = (u_char)((c + ' ') << 1);
  1019.     c =  (ethp->ether_addr_octet[2] << 2) & 0x3c;
  1020.     c |= (ethp->ether_addr_octet[3] >> 6) & 0x03;
  1021.     axhp[2] = (u_char)((c + ' ') << 1);
  1022.     c =  (ethp->ether_addr_octet[3]     ) & 0x3f;
  1023.     axhp[3] = (u_char)((c + ' ') << 1);
  1024.     c =  (ethp->ether_addr_octet[4] >> 2) & 0x3f;
  1025.     axhp[4] = (u_char)((c + ' ') << 1);
  1026.     c =  (ethp->ether_addr_octet[4] << 4) & 0x30;
  1027.     c |= (ethp->ether_addr_octet[5] >> 4) & 0x0f;
  1028.     axhp[5] = (u_char)((c + ' ') << 1);
  1029.     c =  (ethp->ether_addr_octet[5]     ) & 0x0f;
  1030.     axhp[6] = (u_char)((c + '0') << 1);
  1031.  
  1032. done:
  1033. #ifdef DEBUG2
  1034.     for(i=0; i<6; i++)
  1035.         printf("%2x.", axhp[i]);
  1036.     printf("%2x '", axhp[6]);
  1037.  
  1038.     for(i=0; i<6; i++)
  1039.         printf("%c", (axhp[i] >> 1) & 0x7f );
  1040.     printf("-%c'\n", ((axhp[6] & 0x7f) >> 1) & 0x7f );
  1041. #endif
  1042.     return;
  1043. }
  1044.  
  1045. print_ax25addr(axhp)
  1046. u_char *axhp;
  1047. {
  1048.     int i;
  1049.  
  1050. #ifdef DEBUG2
  1051.     for(i=0; i<6; i++)
  1052.         printf("%2x.", axhp[i]);
  1053.     printf("%2x", axhp[6]);
  1054. #endif
  1055.  
  1056.     printf("(");
  1057.     for(i=0; i<6; i++)
  1058.         printf("%c", (axhp[i]>>1) & 0x7f );
  1059.     printf("-%c)", ((axhp[6]&0x7f)>>1) & 0x7f );
  1060. }
  1061.  
  1062. ax25_arpdebug(m0)
  1063. struct mbuf *m0;
  1064. {
  1065.     struct mbuf *m;
  1066.     int len, n;
  1067.     u_char *cp;
  1068.  
  1069.     len = 0;
  1070.     for(m=m0; m; m=m->m_next) {
  1071.         printf("*");
  1072.         cp = mtod(m, u_char *);
  1073.         n = m->m_len;
  1074.         while(n-->0) {
  1075.             if( !(len++ % 16) )
  1076.                 printf("\n\t");
  1077.             printf("%2x ", *cp++);
  1078.         }
  1079.     }
  1080.     if( len % 16 )
  1081.         printf("\n");
  1082. }
  1083.  
  1084.  
  1085. #endif    /* !(NAX > 0) */
  1086.  
  1087.